<script setup lang="ts">
import { Edit, Filter, Location, List, MoonNight, Sunny, Sunrise, User, Picture } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import type { UploadFile } from 'element-plus'
import type { UploadInstance, UploadProps, UploadRawFile } from 'element-plus'
import { genFileId } from 'element-plus'
import Map from '@arcgis/core/Map.js'
import MapView from '@arcgis/core/views/MapView.js'
import FeatureLayer from '@arcgis/core/layers/FeatureLayer.js'
//import Query from '@arcgis/core/rest/support/Query.js'
import Track from '@arcgis/core/widgets/Track.js'
import Sketch from '@arcgis/core/widgets/Sketch.js'
import GraphicsLayer from '@arcgis/core/layers/GraphicsLayer.js'
import { onMounted, ref } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
import { registerActivity } from '@/api/activity'
import { createActivityRequest } from '@/types/activity'
import Geometry from '@arcgis/core/geometry/Geometry.js'
import Graphic from '@arcgis/core/Graphic.js'
//import WebTileLayer from '@arcgis/core/layers/WebTileLayer'
import { useRoute } from 'vue-router'
import { getActivitiesBriefList, getActivityChief, getFilterActivities } from '@/api/activity'
import { getActivitiesBriefRequest, getActivitiesBriefResponse, getActivityChiefResponse, getActivityFilterRequest } from '@/types/activity'
import dayjs from 'dayjs'
import { formattingSqlIN } from '@/utils/publicMethod'
import Query from '@arcgis/core/rest/support/Query'
import Handles from '@arcgis/core/core/Handles.js'
import FeatureLayerView from '@arcgis/core/views/Layers/FeatureLayerView.js'
import { AnnotationLayer, SpaceLayer } from '@/utils/TianDiTuExtension'
import SpatialReference from '@arcgis/core/geometry/SpatialReference.js'

//路由
const route = useRoute()
//初始化地图容器
const mapViewContainer = ref<HTMLDivElement>()

//添加要素图层
const voluntaryLayer = new FeatureLayer({
  url: 'https://services8.arcgis.com/CmXfu09loK81if9H/arcgis/rest/services/VoluntaryActivityLayer/FeatureServer/1',
  outFields: ['*']
})

//自定筛选活动 使用definitionExpression
const filterActivitiesData = await getFilterActivities(
  new getActivityFilterRequest(undefined, undefined, undefined, undefined, dayjs().format('YYYY/MM/DD HH:mm:ss'), undefined)
)
//筛选条件
let insql = formattingSqlIN(filterActivitiesData.data)
console.log(insql)
voluntaryLayer.definitionExpression = `ActivityId in(${insql})`
//筛选抽屉数据
const filterDrawer = ref(false)
const filterFormData = ref<getActivityFilterRequest>({})
const filterForm = ref<FormInstance>()
//筛选方法
const openFilter = () => {
  filterDrawer.value = true
}
const cancelFilter = () => {
  filterDrawer.value = false
}
const confirmFilter = async () => {
  //用户筛选活动 使用definitionExpression
  const filterActivitiesData = await getFilterActivities(filterFormData.value)
  //筛选条件
  insql = formattingSqlIN(filterActivitiesData.data)
  console.log(insql)
  voluntaryLayer.definitionExpression = `ActivityId in(${insql})`
  filterDrawer.value = false
}

//筛选表单验证
const filterRules = ref<FormRules<getActivityFilterRequest>>({
  activityName: [{ required: false, message: '请输入活动名称', trigger: 'blur' }],
  activityTypes: [{ required: false, message: '请选择活动类型', trigger: 'blur' }],
  activityDetailAddress: [{ required: false, message: '请输入活动详细地址', trigger: 'blur' }],
  activityStartTime: [{ required: false, message: '请选择活动开始时间', trigger: 'blur' }],
  activityCompleteTime: [{ required: false, message: '请选择活动结束时间', trigger: 'blur' }]
})

//初始化地图
const map = new Map({
  // basemap styles service
  basemap: {
    // style: {
    //   id: 'osm/streets',
    //   language: 'zh-CN'
    // }
    baseLayers: [SpaceLayer, AnnotationLayer]
  },
  layers: []
})
//console.log(voluntaryLayer)
map.add(voluntaryLayer)

//初始化mapview
const view = new MapView({
  map: map,
  center: [116.7963581069489, 36.53729500053177], // Longitude, latitude
  zoom: 13 // Zoom level
})

const track = new Track({
  view: view
})

//创建出一个临时的图层 用于绘制sKetch图层
const sketchLayer = new GraphicsLayer()
map.add(sketchLayer)

//定义多选活动框
const multiSelect = ref(false)
const activityDetail = ref(false)

const elTableData = ref<getActivitiesBriefResponse[]>([])
const chiefActivityData = ref<getActivityChiefResponse>()
let highlightHandle: Handles = new Handles()
//定义查询志愿详情并展示函数
const queryActivityDetail = async (queryActivityId: number) => {
  if (!queryActivityId) {
    console.log(queryActivityId)
    console.log('选择查询活动要素之后再查询')
    return
  }
  const query = new Query()
  // 设置查询条件
  query.where = `ActivityId = '${queryActivityId}'`
  // 返回几何信息
  query.returnGeometry = true
  // 返回所有字段
  query.outFields = ['*']
  // 执行查询
  const response = await voluntaryLayer.queryFeatures(query)
  // 如果没有查询到结果，则直接返回
  if (response.features.length === 0) {
    return
  }
  // 获取查询到的第一个结果
  const foundFeature = response.features[0]
  // 找到对应的视图
  const featureLayerView = await view.whenLayerView(voluntaryLayer) as FeatureLayerView
  // 移除所有的高亮处理
  highlightHandle.removeAll()
  console.log(featureLayerView)
  // 执行高亮处理
  const newHighlightHandle = featureLayerView?.highlight(foundFeature)
  // 添加到高亮处理中
  highlightHandle.add(newHighlightHandle)
  // 设置活动详情弹出框内容 从数据库中获取
  const result = await getActivityChief(queryActivityId)

  chiefActivityData.value = result.data
  //弹出详情框
  activityDetail.value = true
}

//定义地图点击动作
view.on('click', async function (event) {
  // 转换空间参考
  const mapPoint = event.mapPoint.clone()
  mapPoint.spatialReference = new SpatialReference({ wkid: 4326 })
  //查询出来对应要素图层的对象，如果有那就去数据库把组织者输入的取出，通过屏幕右侧弹出框展示
  const query = new Query()
  query.geometry = mapPoint
  query.where = `ActivityId in(${insql})`
  query.distance = 0.1
  query.units = 'miles'
  query.spatialRelationship = 'intersects'
  query.returnGeometry = true
  query.outFields = ['*']
  const res = await voluntaryLayer.queryFeatures(query)
  if (res.features.length > 0) {
    //查询到志愿，准备去查询去数据库
    console.log(res.features)
    //判断选择的活动数量大于1
    if (res.features.length > 1) {
      //弹出选择框看用户是需要查看哪个志愿活动详情
      let Request = new getActivitiesBriefRequest(new Array<number>())
      //去查询选择活动的详情
      res.features.forEach((item) => {
        //根据活动id去数据库查询活动详情
        let activityId: string = item.attributes.ActivityId
        Request.activityIds.push(Number(activityId))
      })
      let activityBriefListResult = await getActivitiesBriefList(Request)
      //console.log(activityBriefListResult)
      elTableData.value = activityBriefListResult.data
      multiSelect.value = true
    } else {
      //查询出志愿详情展示
      queryActivityDetail(Number(res.features[0].attributes.ActivityId))
    }
  } else {
    console.log('不存在志愿')
  }
})

//存在多个活动时，选择的处理函数
const selectHandle = (row: getActivitiesBriefResponse) => {
  //拿到l具体要显示活动的详细情况，准备展示该活动的详细信息
  queryActivityDetail(row.activityId)
  multiSelect.value = false
}

//初始化抽屉配置
const drawer = ref(false)
const direction = ref('rtl')
const drawerClose = (done: () => void) => {
  sketchLayer.removeAll()
  done()
}

//创建活动配置
let createActivityGraphic: Geometry
const CreateActivity = async () => {
  //提醒用户用鼠标绘图
  ElMessage.info('请用鼠标绘图')
  //先创建出画图组件
  const sketch = new Sketch({
    view: view,
    layer: sketchLayer,
    visible: false
  })
  //使用画图工具，画出一个志愿活动范围
  sketch.create('polygon', { mode: 'click' })

  sketch.on('create', function (event) {
    //console.log(event.state)
    if (event.state === 'complete') {
      createActivityGraphic = event.graphic.geometry
      console.log(event.graphic.geometry)
      drawer.value = true
      sketch.cancel()
    }
  })
}

//创建填写活动详情的表单数据
const formData = ref({
  name: '',
  activityStartTime: '',
  activityCompleteTime: '',
  type: 0,
  desc: '',
  address: '',
  imgBase64: ''
})
//表单ref对象
const activityForm = ref<FormInstance>()
//创建表单校验规则
const activityRules = {
  name: [{ required: true, message: '请输入活动名称', trigger: 'blur' }],
  activityStartTime: [{ required: true, message: '请输入活动开始时间', trigger: 'blur' }],
  activityCompleteTime: [{ required: true, message: '请输入活动结束时间', trigger: 'blur' }],
  type: [{ required: true, message: '请选择活动类型', trigger: 'blur' }],
  desc: [{ required: true, message: '请输入活动详情', trigger: 'blur' }],
  address: [{ required: true, message: '请输入活动地址', trigger: 'blur' }]
}
//处理宣传图片选择问题
const onSelectFile = (uploadFile: UploadFile) => {
  if (
    uploadFile.raw?.type !== 'image/jpeg' &&
    uploadFile.raw?.type !== 'image/png' &&
    uploadFile.raw?.type !== 'image/gif' &&
    uploadFile.raw?.type !== 'image/bmp'
  ) {
    ElMessage.error('请选择图片文件')
    return
  }
  // 基于 FileReader 读取图片做预览
  const reader = new FileReader()
  reader.readAsDataURL(uploadFile.raw!)
  reader.onload = () => {
    //将图片转为base64格式
    formData.value.imgBase64 = reader.result?.toString()!
    //console.log(formData.value.imgBase64)
  }
}
const formSubmit = async () => {
  sketchLayer.removeAll()
  //验证表单
  await activityForm.value?.validate()
  console.log(formData.value.type)
  //先去提交信息给后端，拿到创建好的活动ID
  const res = await registerActivity(
    new createActivityRequest(
      formData.value.name,
      formData.value.activityStartTime,
      formData.value.activityCompleteTime,
      formData.value.type,
      formData.value.desc,
      formData.value.address,
      formData.value.imgBase64
    )
  )
  console.log(res.data.activityId)

  //拿到后端创建好的活动ID，然后把空间要素提交给Arcgis online 在其中保存好活动ID
  let attributes: any = {}
  attributes['ActivityId'] = res.data.activityId
  console.log(createActivityGraphic)
  let activityGraphic = new Graphic({
    geometry: createActivityGraphic,
    attributes: attributes
  })
  voluntaryLayer.applyEdits({
    addFeatures: [activityGraphic]
  })
  drawer.value = false
}
//处理宣传图片超出的问题
const uploadRef = ref<UploadInstance>()
const handleExceed: UploadProps['onExceed'] = (files) => {
  uploadRef.value!.clearFiles()
  const file = files[0] as UploadRawFile
  file.uid = genFileId()
  uploadRef.value!.handleStart(file)
  //console.log(formData.value.imgBase64)
}

//待地图视图加载完成后加入
view.when(async () => {
  //添加进入地图视图
  view.ui.add(track, 'top-left')
  //自动启动定位器，但是由于电脑没定位模块，定位不准确，默认关闭
  //track.start()
  //个人志愿活动展示详情数据
  if (route.query.myOrganizedActivityId) {
    await queryActivityDetail(Number(route.query.myOrganizedActivityId))
  }
})

//待dom元素完成后加入
onMounted(async () => {
  view.container = mapViewContainer.value!
  view.ui.add('CreateActivityBtn', 'top-right')
  view.ui.add('editActivityGallery', 'top-right')
})
</script>
<template>
  <div id="mapViewContainer" ref="mapViewContainer" class="mapView">
    <el-button type="primary" :icon="Edit" circle id="CreateActivityBtn" @click="CreateActivity" />
    <el-button type="primary" :icon="Filter" circle id="editActivityGallery" @click="openFilter" />
  </div>
  <!-- 创建活动抽屉 -->
  <el-drawer v-model="drawer" title="填写志愿活动基础信息" :direction="direction" :before-close="drawerClose">
    <el-form :model="formData" ref="activityForm" label-width="120px" label-position="left" :rules="activityRules">
      <el-form-item label="活动名称" prop="name">
        <el-input v-model="formData.name" />
      </el-form-item>
      <el-form-item label="活动开始时间" prop="activityStartTime">
        <el-date-picker
          v-model="formData.activityStartTime"
          type="datetime"
          placeholder="选择日期时间"
          format="YYYY/MM/DD HH:mm:ss"
          value-format="YYYY-MM-DD H:m:s"
        />
      </el-form-item>
      <el-form-item label="活动结束时间" prop="activityCompleteTime">
        <el-date-picker
          v-model="formData.activityCompleteTime"
          type="datetime"
          placeholder="选择日期时间"
          format="YYYY/MM/DD HH:mm:ss"
          value-format="YYYY-MM-DD H:m:s"
        />
      </el-form-item>
      <el-form-item label="活动类型" prop="type">
        <el-radio-group v-model="formData.type">
          <el-radio label="1">社区建设</el-radio>
          <el-radio label="2">大型赛会</el-radio>
          <el-radio label="3">海外服务</el-radio>
          <el-radio label="4">应急救助</el-radio>
          <el-radio label="5">扶贫开发</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="活动详细描述" prop="desc">
        <el-input v-model="formData.desc" type="textarea" />
      </el-form-item>
      <el-form-item label="活动详细地址" prop="address">
        <el-input v-model="formData.address" type="textarea" />
      </el-form-item>
      <el-form-item label="活动宣传图片">
        <el-upload
          ref="uploadRef"
          :auto-upload="false"
          class="upload-demo"
          :show-file-list="true"
          :on-exceed="handleExceed"
          :limit="1"
          :on-change="onSelectFile"
          accept=".jpg,.png,.gif,.bmp"
        >
          <template #trigger>
            <el-button type="primary">选择图片</el-button>
          </template>
          <template #tip>
            <div class="el-upload__tip">请选择jpg/png/gif/bmp图片文件</div>
          </template>
        </el-upload>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="formSubmit">确认提交</el-button>
      </el-form-item>
    </el-form>
  </el-drawer>
  <!-- 活动多选框 -->
  <el-dialog v-model="multiSelect" title="该区域存在多个活动，请选择具体的一个活动，我们将为您展示它的详细信息">
    <el-table :data="elTableData" :border="true" height="250" style="width: 100%">
      <el-table-column prop="activityName" label="活动名称" />
      <el-table-column prop="activityOrganizerName" label="组织者名称" />
      <el-table-column label="操作">
        <template #default="scoped">
          <el-button type="primary" @click="selectHandle(scoped.row)">确定</el-button>
        </template>
      </el-table-column>
    </el-table>
  </el-dialog>
  <!-- 活动详情展示框 -->
  <el-dialog v-model="activityDetail" title="展示" width="70%">
    <el-descriptions class="margin-top" title="活动详情" :column="3" size="large" :border="true">
      <template #extra> </template>
      <el-descriptions-item>
        <template #label>
          <div class="cell-item">
            <el-icon :style="8">
              <MoonNight />
            </el-icon>
            活动名称
          </div>
        </template>
        {{ chiefActivityData?.activityName }}
      </el-descriptions-item>
      <el-descriptions-item>
        <template #label>
          <div class="cell-item">
            <el-icon :style="8">
              <user />
            </el-icon>
            组织者名称
          </div>
        </template>
        {{ chiefActivityData?.organizerName }}
      </el-descriptions-item>
      <el-descriptions-item>
        <template #label>
          <div class="cell-item">
            <el-icon :style="8">
              <Sunny />
            </el-icon>
            活动起始时间
          </div>
        </template>
        {{ dayjs(chiefActivityData?.activityStartTime).format('YYYY-MM-DD HH:mm:ss') }}
      </el-descriptions-item>
      <el-descriptions-item>
        <template #label>
          <div class="cell-item">
            <el-icon :style="8">
              <Sunrise />
            </el-icon>
            活动截止时间
          </div>
        </template>
        {{ dayjs(chiefActivityData?.activityCompleteTime).format('YYYY-MM-DD HH:mm:ss') }}
      </el-descriptions-item>
      <el-descriptions-item>
        <template #label>
          <div class="cell-item">
            <el-icon :style="8">
              <List />
            </el-icon>
            活动详细描述
          </div>
        </template>
        {{ chiefActivityData?.activityDescription }}
      </el-descriptions-item>
      <el-descriptions-item>
        <template #label>
          <div class="cell-item">
            <el-icon :style="8">
              <Location />
            </el-icon>
            活动详细地址
          </div>
        </template>
        {{ chiefActivityData?.activityDetailAddress }}
      </el-descriptions-item>
      <el-descriptions-item>
        <template #label>
          <div class="cell-item">
            <el-icon :style="8">
              <Filter />
            </el-icon>
            活动类别
          </div>
        </template>
        {{ chiefActivityData?.activityTypes }}
      </el-descriptions-item>
      <el-descriptions-item v-if="chiefActivityData?.photoBase64 !== ''">
        <template #label>
          <div class="cell-item">
            <el-icon :style="8">
              <Picture />
            </el-icon>
            活动宣传图片
          </div>
        </template>
        <el-image style="width: 200px; height: 200px" :src="chiefActivityData?.photoBase64" fit="contain" />
      </el-descriptions-item>
    </el-descriptions>
  </el-dialog>
  <!-- 活动筛选抽屉 -->
  <el-drawer v-model="filterDrawer" direction="rtl" size="40%">
    <template #header>
      <h4>请确定筛选条件</h4>
    </template>
    <template #default>
      <el-form :model="filterFormData" ref="filterForm" label-position="left" :rules="filterRules">
        <el-form-item label="名称（支持模糊查找）" prop="activityName">
          <el-input v-model="filterFormData.activityName" placeholder="请输入活动名称" />
        </el-form-item>
        <el-form-item label="组织者名称（支持模糊查找）" prop="organizerName">
          <el-input v-model="filterFormData.organizerName" placeholder="请输入组织者名称" />
        </el-form-item>
        <el-form-item label="活动类型" prop="activityTypes">
          <el-radio-group v-model="filterFormData.activityTypes">
            <el-radio label="1">社区建设</el-radio>
            <el-radio label="2">大型赛会</el-radio>
            <el-radio label="3">海外服务</el-radio>
            <el-radio label="4">应急救助</el-radio>
            <el-radio label="5">扶贫开发</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="活动开始时间（查询在这之后的活动）" prop="activityStartTime">
          <el-date-picker
            v-model="filterFormData.activityStartTime"
            type="datetime"
            placeholder="选择日期时间"
            format="YYYY/MM/DD HH:mm:ss"
            value-format="YYYY-MM-DD H:m:s"
          />
        </el-form-item>
        <el-form-item label="活动截止时间（查询在这之前的活动）" prop="activityCompleteTime">
          <el-date-picker
            v-model="filterFormData.activityCompleteTime"
            type="datetime"
            placeholder="选择日期时间"
            format="YYYY/MM/DD HH:mm:ss"
            value-format="YYYY-MM-DD H:m:s"
          />
        </el-form-item>
        <el-form-item label="活动模糊地址（只要包含）" prop="activityDetailAddress">
          <el-input v-model="filterFormData.activityDetailAddress" placeholder="请输入活动模糊地址" />
        </el-form-item>
      </el-form>
    </template>
    <template #footer>
      <div style="flex: auto">
        <el-button @click="cancelFilter">取消</el-button>
        <el-button type="primary" @click="confirmFilter">确定</el-button>
      </div>
    </template>
  </el-drawer>
</template>
<style scoped lang="scss">
.mapView {
  width: 100%;
  height: 100%;
}
</style>
